<?php
require_once("Wzx.php");
require_once("Action.php");
require_once(SITE_ROOT.'/includes/tools/id.php');
//require_once(SITE_ROOT.'/includes/levels.php');
abstract class WzxElement {
    protected $id;  // element id, globally unique
    protected $name; // name of this element
    protected $default_privacy; // default privacy of this object
    protected $day_max_points; // Max points every day of this object

    //0=don't display, 1=only between the source and the target, 2=friends, 3=all
    protected static $db_useraction_limit = 200;

    public function __construct($id, $name, $default_privacy,$day_max_points) {
        $this->id = $id;
        $this->name = $name;
        $this->default_privacy = $default_privacy;
        $this->day_max_points = $day_max_points;
    }

    // returns the id of this application
    public function getID() {
        return $this->id;
    }

    // returns the name of this application
    public function getName() {
        return $this->name;
    }

    // returns the default privacy of this facekoo object
    public function getDefaultPrivacy() {
        return $this->default_privacy;
    }

    public function getDayMaxPoints() {
        return $this->day_max_points;
    }

    // fetches the array of arrays of actions (actions[elementid]) from friends (好友小动作)
    public static final function getAllFriendActionsByDate($requesting_uid, $date, $dboff = 0) {
        global $mysqli_read;
        if ($requesting_uid == '888' || $requesting_uid == '3')
        return;
        $sql = "SELECT friendlist,typelist FROM fk_bagua_setting WHERE userid='$requesting_uid'";
        $result = $mysqli_read->query($sql);
        if($result->num_rows==1){
            $row=$result->fetch_array(MYSQLI_ASSOC);
            if($row['friendlist']!=""){
                $temparray=explode(",",$row['friendlist']);
                foreach($temparray as $key=>&$value){
                    $value="'".$value."'";
                }
                $arr=implode(",",$temparray);
                $source_limits=" AND source_uid NOT IN (".$arr.")";
                $target_limits=" AND target_uid NOT IN (".$arr.")";
            }
            if($row['typelist']!=""){
                $temparray=explode(",",$row['typelist']);
                foreach($temparray as $key=>&$value){
                    $value="'".$value."'";
                }
                $arr=implode(",",$temparray);
                $source_limits.=" AND elementid NOT IN (".$arr.")";
                $target_limits.=" AND elementid NOT IN (".$arr.")";
            }
        }else{
            $source_limits="";
            $target_limits="";
        }

        $sql =<<<END
SELECT fk_useraction_2.id AS id,elementid,
       source_uid,source.nickname AS source_nickname,source.sex AS source_sex,source.username AS source_username,source.realname AS source_realname,
       target_uid,target.nickname AS target_nickname,target.username AS target_username,target.realname AS target_realname,
       whatdesc,valuedesc,subtime,target_read,privacy 
FROM fk_useraction_2 USE INDEX (date_source)
JOIN fk_friends AS friend ON friend.friendid=source_uid
JOIN fk_users AS source ON source_uid=source.id
LEFT JOIN fk_users AS target ON target_uid=target.id
WHERE friend.myid='$requesting_uid'
AND (source_uid <> '$requesting_uid' AND (target_uid <> '$requesting_uid' OR target_uid IS NULL))
AND source_uid_deleted = 0
AND date='$date' AND subtime<now() 
AND privacy >= 2
AND space_display = 1 
AND hide='0' 
$source_limits
UNION
SELECT fk_useraction_2.id AS id,elementid,
       source_uid,source.nickname AS source_nickname,source.sex AS source_sex,source.username AS source_username,source.realname AS source_realname,
       target_uid,target.nickname AS target_nickname,target.username AS target_username,target.realname AS target_realname,
       whatdesc,valuedesc,subtime,target_read,privacy 
FROM fk_useraction_2 USE INDEX (date_target)
JOIN fk_friends AS friend ON friend.friendid=target_uid
JOIN fk_users AS source ON source_uid=source.id
JOIN fk_users AS target ON target_uid=target.id
WHERE friend.myid='$requesting_uid'
AND source_uid <> '$requesting_uid' AND target_uid <> '$requesting_uid'
AND source_uid_deleted = 0
AND date='$date'
AND privacy >= 2 AND subtime<now() 
AND space_display = 1 
AND hide='0' 
$target_limits
ORDER BY subtime DESC 
END;
        $sql .= " LIMIT $dboff,".self::$db_useraction_limit;
        $result = $mysqli_read->query($sql);
        while ($row = $result->fetch_array(MYSQLI_ASSOC)) {
            $elementid = $row['elementid'];
            $action_arr[$elementid][] = new Action($row['id'],$row['elementid'],$row['source_uid'],$row['source_nickname'],$row['source_username'],$row['source_realname'],$row['source_sex'],$row['target_uid'],$row['target_nickname'],$row['target_username'],$row['target_realname'],$row['whatdesc'],$row['valuedesc'],$row['subtime'],$row['target_read'],$row['privacy']);
        }
        return $action_arr;
    }

    // fetches the array of actions for the given user (自己小动作)
    public static final function getAllUserActionsByDate($requesting_uid, $uid, $date, $dboff = 0) {
        global $mysqli_read;

        if ($uid === $requesting_uid) {
            $sql =<<<END
SELECT fk_useraction_2.id AS id,elementid,
       source_uid,source.nickname as source_nickname,source.sex AS source_sex,source.username as source_username,source.realname as source_realname,
       target_uid,target.nickname as target_nickname,target.username as target_username,target.realname as target_realname,
       whatdesc,valuedesc,subtime,privacy
FROM fk_useraction_2 USE INDEX (date_source)
JOIN fk_users AS source ON source_uid=source.id
LEFT JOIN fk_users AS target ON target_uid=target.id
WHERE source_uid='$uid'
AND source_uid_deleted = 0
AND date='$date' AND subtime<now() 
AND space_display = 1 AND hide='0' 
ORDER BY subtime DESC
END;

} else {
    // fetches all actions by the given user viewable by the requesting user

    $sql =<<<END
SELECT fk_useraction_2.id AS id,elementid,
       source_uid,source.nickname as source_nickname,source.sex AS source_sex,source.username as source_username,source.realname as source_realname,
       target_uid,target.nickname as target_nickname,target.username as target_username,target.realname as target_realname,
       whatdesc,valuedesc,subtime,target_read,privacy
FROM fk_useraction_2 USE INDEX (date_source)
JOIN fk_users AS source ON source_uid=source.id
LEFT JOIN fk_users AS target ON target_uid=target.id
WHERE source_uid='$uid'
AND source_uid_deleted = 0
AND space_display = 1
AND date='$date' AND subtime<now() 
AND hide='0' 
AND (privacy >= 3 
     OR (privacy = 1 AND target_uid='$requesting_uid') 
     OR (privacy = 2 AND '$requesting_uid' IN (SELECT friendid FROM fk_friends WHERE myid='$uid')))
ORDER BY subtime DESC
END;

}
$sql .= " LIMIT $dboff,".self::$db_useraction_limit;
$result = $mysqli_read->query($sql);
while ($row = $result->fetch_array(MYSQLI_ASSOC)) {
    $elementid = $row['elementid'];
    $action_arr[$elementid][] = new Action($row['id'],$row['elementid'],$row['source_uid'],$row['source_nickname'],$row['source_username'],$row['source_realname'],$row['source_sex'],$row['target_uid'],$row['target_nickname'],$row['target_username'],$row['target_realname'],$row['whatdesc'],$row['valuedesc'],$row['subtime'],$row['target_read'],$row['privacy']);
}

return $action_arr;
    }

    // fetches the array of action for the given user for this element
    public function getUserActions($requesting_uid, $uid) {
        global $mysqli_read;

        if ($uid == $requesting_uid) {

            $sql =<<<END
SELECT fk_useraction_2.id AS id,elementid,
       source_uid,source.nickname as source_nickname,source.sex AS source_sex,source.username as source_username,source.realname as source_realname,
       target_uid,target.nickname as target_nickname,target.username as target_username,target.realname as target_realname,
       whatdesc,valuedesc,subtime
FROM fk_useraction_2 
JOIN fk_users AS source ON source_uid=source.id
LEFT JOIN fk_users AS target ON target_uid=target.id
WHERE source_uid='$uid'
AND source_uid_deleted = 0
AND elementid={$this->id}
AND space_display = 1 AND hide='0'  AND subtime<now() 
ORDER BY subtime DESC
END;

} else {

    $sql =<<<END
SELECT fk_useraction_2.id AS id,elementid,
       source_uid,source.nickname as source_nickname,source.sex AS source_sex,source.username as source_username,source.realname as source_realname,
       target_uid,target.nickname as target_nickname,target.username as target_username,target.realname as target_realname,
       whatdesc,valuedesc,subtime,target_read,privacy
FROM fk_useraction_2
JOIN fk_users AS source ON source_uid=source.id
LEFT JOIN fk_users AS target ON target_uid=target.id
WHERE source_uid='$uid'
AND source_uid_deleted = 0 AND subtime<now() 
AND space_display = 1 AND hide='0' 
AND (privacy >= 3 
     OR (target_uid='$requesting_uid' AND privacy = 1) 
     OR (privacy = 2 AND '$requesting_uid' IN (SELECT friendid FROM fk_friends WHERE myid='$uid')))
AND elementid={$this->id}
ORDER BY subtime DESC
END;

}
$result = $mysqli_read->query($sql);
while ($row = $result->fetch_array(MYSQLI_ASSOC)) {
    $action_arr[] = new Action($row['id'],$row['elementid'],$row['source_uid'],$row['source_nickname'],$row['source_username'],$row['source_realname'],$row['source_sex'],$row['target_uid'],$row['target_nickname'],$row['target_username'],$row['target_realname'],$row['whatdesc'],$row['valuedesc'],$row['subtime'],$row['target_read'],$row['privacy']);
    //$action_arr[] = $row;
}
return $action_arr;
    }
    /**
     * 获取某用户最新和最旧的小动作的日期
     *
     * @param $userid：用户ID号
     */

    public static final function getActionMaxMinDate ($userid) {
        global $mysqli_read;
        $sql = "SELECT MAX(date) as maxdate, MIN(date) as mindate FROM fk_useraction_2 WHERE source_uid='$userid' AND source_uid_deleted=0 AND space_display=1 AND hide='0' AND date<>'0000-00-00'";
        $result = $mysqli_read->query($sql);
        if(($row = $result->fetch_array(MYSQLI_ASSOC)) && $row['maxdate']) {
            $date_arr = array("maxdate"=>$row['maxdate'],"mindate"=>$row['mindate']);
            $result->free();
            return $date_arr;
        } else {
            $result->free();
            return false;
        }
    }

    /**
     * 获取某用户好友最新和最旧的小动作的日期
     *
     * @param $userid：用户ID号
     */

    public static final function getFriendsActionMaxMinDate ($userid) {
        global $mysqli_read;
        return array("maxdate"=>date('Y-m-d'),"mindate"=>date('Y-m-d', time()-30*24*60*60));
    }

    /**
     * 获取某用户最新和最旧的大事件的日期
     *
     * @param $userid：用户ID号
     */
    public static final function getNotificationMaxMinDate ($userid) {
        global $mysqli_read;
        $sql = "SELECT MAX(date) as maxdate, MIN(date) as mindate FROM fk_useraction_2 WHERE target_uid='$userid' AND (source_uid<>'$userid' OR notify_self=1) AND notify_target=1 AND hide='0' AND date<>'0000-00-00'";
        $result = $mysqli_read->query($sql);
        if(($row = $result->fetch_array(MYSQLI_ASSOC)) && $row['maxdate']) {
            $date_arr = array("maxdate"=>$row['maxdate'],"mindate"=>$row['mindate']);
            $result->free();
            return $date_arr;
        } else {
            $result->free();
            return false;
        }
    }

    /**
     * 获取某用户最新和最旧的未读的大事件的日期
     *
     * @param $userid：用户ID号
     */
    public static final function getNewNotificationMaxMinDate ($userid) {
        global $mysqli_read;
        $sql = "SELECT MAX(date) as maxdate, MIN(date) as mindate FROM fk_useraction_2 WHERE target_uid='$userid' AND (source_uid<>'$userid' OR notify_self=1) AND notify_target=1 AND target_read='0' AND hide='0' AND date<>'0000-00-00'";
        $result = $mysqli_read->query($sql);
        if(($row = $result->fetch_array(MYSQLI_ASSOC)) && $row['maxdate']) {
            $date_arr = array("maxdate"=>$row['maxdate'],"mindate"=>$row['mindate']);
            $result->free();
            return $date_arr;
        } else {
            $result->free();
            return false;
        }
    }

    public static  function getNewNotificationCount($userid)
    {
        $sql="SELECT count(id) FROM fk_useraction_2 WHERE target_uid='$userid' AND (source_uid<>'$userid' OR notify_self=1) AND target_read=0 AND notify_target=1 AND hide='0' ";
        global $mysqli_read;
        $res=$mysqli_read->query($sql);
        $rs=$res->fetch_array();
        return $rs[0];
    }

    public static  function markNotificationsRead($userid, $time)
    {
        $time = mysql_escape_string($time);
        if($time!="")
        $sql="UPDATE fk_useraction_2 SET target_read=1 WHERE target_uid='$userid' AND target_read=0 AND subtime <= '$time'";
        else
        $sql="UPDATE fk_useraction_2 SET target_read=1 WHERE target_uid='$userid' AND target_read=0";
        global $mysqli_write;
        $res=$mysqli_write->query($sql);
    }

    // updates the action feed for the given user within this application
    public function updateAction($source_uid, $what_desc, $value_desc, $target_uid = 0, $privacy = -1, $notify_self = 0,$source_id="",$hide=0) {
        global $mysqli_write;

        $what_desc = mysql_escape_string($what_desc);
        $value_desc = mysql_escape_string($value_desc);
        $privacy = $privacy == -1 ? $this->default_privacy : $privacy;
        if (is_array($target_uid)) {
            foreach ($target_uid as $uid) {

                $sql ="INSERT INTO fk_useraction_2 (id,elementid, source_uid, target_uid, whatdesc, valuedesc, privacy, notify_self,source_id,hide,date) VALUES ('".get_unique_id()."','{$this->id}', '$source_uid', '$uid','$what_desc', '$value_desc','$privacy','$notify_self','$source_id','$hide',DATE(NOW()))";

                $mysqli_write->query($sql);
            }
        } else {
            $sql ="INSERT INTO fk_useraction_2 (id,elementid, source_uid, target_uid, whatdesc, valuedesc, privacy, notify_self,source_id,hide,date) VALUES ('".get_unique_id()."','{$this->id}', '$source_uid', '$target_uid','$what_desc', '$value_desc','$privacy','$notify_self','$source_id','$hide',DATE(NOW()))";

            $mysqli_write->query($sql);
        }
    }
    public static final function getAllUserNotificationsByDate($userid,$date,$dboff = 0)
    {
        global $mysqli_read;
        $sql =<<<END
SELECT fk_useraction_2.id AS id,elementid,
source_uid,source.nickname AS source_nickname,source.sex AS source_sex,source.username AS source_username,source.realname AS source_realname,
target_uid,target.nickname AS target_nickname,target.username AS target_username,target.realname AS target_realname,
whatdesc,valuedesc,subtime,target_read,privacy
FROM fk_useraction_2
JOIN fk_users AS source ON source_uid=source.id
LEFT JOIN fk_users AS target ON target_uid=target.id
WHERE target_uid='$userid'
AND (source_uid<>'$userid' OR notify_self=1)
AND notify_target=1 AND hide='0' 
AND date='$date' AND subtime<now() 
ORDER BY subtime DESC
END;
        $sql .= " LIMIT $dboff,".self::$db_useraction_limit;
        $result = $mysqli_read->query($sql);
        while ($row = $result->fetch_array(MYSQLI_ASSOC)) {
            $elementid = $row['elementid'];
            $arr[$elementid][] = new Action($row['id'],$row['elementid'],$row['source_uid'],$row['source_nickname'],$row['source_username'],$row['source_realname'],$row['source_sex'],$row['target_uid'],$row['target_nickname'],$row['target_username'],$row['target_realname'],$row['whatdesc'],$row['valuedesc'],$row['subtime'],$row['target_read'],$row['privacy']);
        }
        return $arr;
    }

    public static final function getGlobalRecentActions() {
        global $mysqli_read;
        $sql = "SELECT * FROM fk_global_recent_actions";
        $res = $mysqli_read->query($sql);
        while ($row = $res->fetch_array(MYSQLI_ASSOC)) {
            $elementid = $row['elementid'];
            $arr[$elementid][] = new Action($row['id'],$row['elementid'],$row['source_uid'],$row['source_nickname'],$row['source_username'],$row['source_realname'],$row['source_sex'],$row['target_uid'],$row['target_nickname'],$row['target_username'],$row['target_realname'],$row['whatdesc'],$row['valuedesc'],$row['subtime'],$row['target_read'],$row['privacy']);
        }
        return $arr;
    }


    public function getPoints($uid) {
        global $mysqli_read;
        $sql = "SELECT points FROM fk_users WHERE id='$uid'";
        $result = $mysqli_read->query($sql);
        if ($row=$result->fetch_array(MYSQLI_ASSOC)) {
            return intval($row['points']);
        } else {
            return 0;
        }
    }

    public function addPoints($uid, $points, $extras=false) {
        global $mysqli_write, $mysqli_read,$modules;
        $points = intval($points);

        $res = $mysqli_read->query("select * from fk_userpoints_day where user_id='$uid' and date(subtime)=curdate() and elementid='{$this->id}'");
        
        if($res->num_rows==1) {
            $exist = 1;
            $row = $res->fetch_array(MYSQLI_ASSOC);
            if($this->day_max_points && $row['points']>=$this->day_max_points)
                return true;
        } else {
            $exist = 0;
        }

        $sql = "SELECT points,virtual_career FROM fk_users WHERE id='$uid'";
        $res = $mysqli_read->query($sql);
        if ($res && ($row = $res->fetch_array(MYSQLI_ASSOC))) {
            $current_points = intval($row['points']);
            $virtual_career = $row['virtual_career'];
            $sql = "UPDATE fk_users SET points=points+$points";
            if ($extras) {
                if (is_array($extras)) {
                    foreach ($extras as $extra) {
                        $sql .= ",points_$extra=points_$extra+$points";
                    }
                } else {
                    $sql .= ",points_$extras=points_$extras+$points";
                }
            }
            $sql .= " WHERE id='$uid'";
            $mysqli_write->query($sql);
            if($mysqli_write->errno==0) {
                $newlevel = self::getLevelFromPoints($current_points+$points);
                if (self::getLevelFromPoints($current_points) != $newlevel) {
                    $app = FaceKoo::getElementObject(5);
                    if ($points > 0) {
                        // level advance
                        $app->updateAction($uid, 20, "$virtual_career\001$newlevel", $uid, -1, 1);
                    } else {
                        // level decline
                        $app->updateAction($uid, 21, "$virtual_career\001$newlevel", $uid, -1, 1);
                    }
                }

                
                if($exist) {                
                    $sql = "update fk_userpoints_day set points=points+$points,subtime=now() where user_id='$uid' and elementid='{$this->id}'";
                } else {
                    $sql = "replace into fk_userpoints_day(user_id,points,subtime,elementid) values ('$uid',$points,now(),'{$this->id}')";
                }
                $mysqli_write->query($sql);
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }


    public static function getLevelFromPoints($points) {
        global $levels;
        foreach ($levels as $level => $min_points) {
            if ($points < $min_points) {
                return $level-1;
            }
        }
        return $level;
    }

    public function getPointsToNextLevel($points) {
        global $levels;
        foreach ($levels as $level => $min_points) {
            if ($points < $min_points) {
                return $min_points-$points;
            }
        }
        return 0;
    }
}
?>
